{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Assignment-03 First Step of Machine Learning: Model and Evaluation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "同学们，今天我们的学习了基本的机器学习概念，相比你已经对机器学习的这些方法有一个基本的认识了。值得说明的是，机器学习不仅仅是一系列方法，更重要的是一种思维体系，即：依据以往的、现有的数据，构建某种方法来解决未见过的问题。而且决策树，贝叶斯只是实现这个目标的一个方法，包括之后的神经网络。很有可能有一天，神经网络也会被淘汰，但是重要的是我们要理解机器学习的目标，就是尽可能的自动化解决未知的问题。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1571556399207&di=4a97dc15ad08dd49d3748d1edf6109b3&imgtype=0&src=http%3A%2F%2Fc.hiphotos.baidu.com%2Fzhidao%2Fwh%3D450%2C600%2Fsign%3Dae742c6aedcd7b89e93932873a146e91%2F5d6034a85edf8db1b16050c40223dd54574e74c7.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Part-1 Programming Review 编程回顾"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. Re-code the Linear-Regression Model using scikit-learning(10 points)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<评阅点>： \n",
    "> + 是否完成线性回归模型 (4')\n",
    "+ 能够进行预测新数据(3')\n",
    "+ 能够进行可视化操作(3')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.1 输入数据，标签数据随机生成"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# you code here\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "random_data = np.random.random((20, 2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1.29617676e-01, 5.20792377e-02],\n",
       "       [4.57846537e-01, 6.36050340e-01],\n",
       "       [5.72513065e-01, 1.67464019e-02],\n",
       "       [9.74587842e-01, 7.53986093e-01],\n",
       "       [6.33325718e-02, 6.13484832e-01],\n",
       "       [1.86052390e-01, 6.14407401e-01],\n",
       "       [7.95712504e-01, 7.68112504e-01],\n",
       "       [1.62786431e-04, 2.78860839e-01],\n",
       "       [1.51741852e-01, 1.85925671e-01],\n",
       "       [6.51408578e-01, 6.31725886e-01],\n",
       "       [6.17132849e-01, 3.43057256e-01],\n",
       "       [7.89150353e-01, 2.51046053e-01],\n",
       "       [4.02373523e-01, 2.41793290e-01],\n",
       "       [2.21734913e-01, 3.64702528e-01],\n",
       "       [6.51597728e-01, 5.24734916e-01],\n",
       "       [3.30260143e-01, 2.90089906e-01],\n",
       "       [4.85565043e-01, 4.39791682e-01],\n",
       "       [5.64424809e-01, 4.02374095e-01],\n",
       "       [1.45453941e-01, 1.96370309e-01],\n",
       "       [5.42013545e-01, 4.11908238e-01]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "random_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 取每个列表中的第一个值，作为输入\n",
    "x = random_data[:,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1.29617676e-01, 4.57846537e-01, 5.72513065e-01, 9.74587842e-01,\n",
       "       6.33325718e-02, 1.86052390e-01, 7.95712504e-01, 1.62786431e-04,\n",
       "       1.51741852e-01, 6.51408578e-01, 6.17132849e-01, 7.89150353e-01,\n",
       "       4.02373523e-01, 2.21734913e-01, 6.51597728e-01, 3.30260143e-01,\n",
       "       4.85565043e-01, 5.64424809e-01, 1.45453941e-01, 5.42013545e-01])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 取每个元素的第二个值，作为标签\n",
    "y = random_data[:,1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.05207924, 0.63605034, 0.0167464 , 0.75398609, 0.61348483,\n",
       "       0.6144074 , 0.7681125 , 0.27886084, 0.18592567, 0.63172589,\n",
       "       0.34305726, 0.25104605, 0.24179329, 0.36470253, 0.52473492,\n",
       "       0.29008991, 0.43979168, 0.4023741 , 0.19637031, 0.41190824])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x116b49ac8>"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.2 假设函数定义"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义假设函数,随便定义一个假设函数，生成y\n",
    "def assuming_func(x, k, b):\n",
    "    return k*x + b + random.randint(-4, 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_ = [assuming_func(x_, 11, 4) for x_ in x]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[5.425794434914404,\n",
       " 13.036311911763388,\n",
       " 6.297643717273708,\n",
       " 12.720466263854036,\n",
       " 3.6966582896509736,\n",
       " 4.046576293036411,\n",
       " 12.752837544648749,\n",
       " 3.00179065073808,\n",
       " 8.669160375512659,\n",
       " 15.165494353829773,\n",
       " 11.788461338669634,\n",
       " 11.680653880230947,\n",
       " 8.426108753386398,\n",
       " 3.43908404144823,\n",
       " 12.16757501276846,\n",
       " 4.632861573833942,\n",
       " 7.341215471290521,\n",
       " 6.2086729039228175,\n",
       " 8.599993355815545,\n",
       " 12.96214899476227]"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x116c8be10>"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### *\n",
    "为什么要用numpy\n",
    "\n",
    "    Python中提供了list容器，可以当作数组使用。但列表中的元素可以是任何对象，因此列表中保存的是对象的指针，这样一来，为了保存一个简单的列表[1,2,3]。就需要三个指针和三个整数对象。对于数值运算来说，这种结构显然不够高效。\n",
    "    Python虽然也提供了array模块，但其只支持一维数组，不支持多维数组(在TensorFlow里面偏向于矩阵理解)，也没有各种运算函数。因而不适合数值运算。\n",
    "    NumPy的出现弥补了这些不足。\n",
    "\n",
    "（——摘自张若愚的《Python科学计算》）\n",
    "————————————————\n",
    "版权声明：本文为CSDN博主「furuit」的原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接及本声明。\n",
    "原文链接：https://blog.csdn.net/fu6543210/article/details/83240024"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_ = np.array(y_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 5.42579443, 13.03631191,  6.29764372, 12.72046626,  3.69665829,\n",
       "        4.04657629, 12.75283754,  3.00179065,  8.66916038, 15.16549435,\n",
       "       11.78846134, 11.68065388,  8.42610875,  3.43908404, 12.16757501,\n",
       "        4.63286157,  7.34121547,  6.2086729 ,  8.59999336, 12.96214899])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.3 调用线性模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LinearRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1.29617676e-01, 4.57846537e-01, 5.72513065e-01, 9.74587842e-01,\n",
       "       6.33325718e-02, 1.86052390e-01, 7.95712504e-01, 1.62786431e-04,\n",
       "       1.51741852e-01, 6.51408578e-01, 6.17132849e-01, 7.89150353e-01,\n",
       "       4.02373523e-01, 2.21734913e-01, 6.51597728e-01, 3.30260143e-01,\n",
       "       4.85565043e-01, 5.64424809e-01, 1.45453941e-01, 5.42013545e-01])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### reshape(-1, 1)\n",
    "列数变成1，行数自动计算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1.29617676e-01],\n",
       "       [4.57846537e-01],\n",
       "       [5.72513065e-01],\n",
       "       [9.74587842e-01],\n",
       "       [6.33325718e-02],\n",
       "       [1.86052390e-01],\n",
       "       [7.95712504e-01],\n",
       "       [1.62786431e-04],\n",
       "       [1.51741852e-01],\n",
       "       [6.51408578e-01],\n",
       "       [6.17132849e-01],\n",
       "       [7.89150353e-01],\n",
       "       [4.02373523e-01],\n",
       "       [2.21734913e-01],\n",
       "       [6.51597728e-01],\n",
       "       [3.30260143e-01],\n",
       "       [4.85565043e-01],\n",
       "       [5.64424809e-01],\n",
       "       [1.45453941e-01],\n",
       "       [5.42013545e-01]])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.reshape(-1, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 输入数据，标签，训练模型\n",
    "model = LinearRegression().fit(x.reshape(-1, 1), y_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.5680675885657651"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#线性回归的scroe方法得到的是决定系数R平方\n",
    "#评估模型:决定系数R平方\n",
    "model.score(x.reshape(-1, 1), y_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 回归系数\n",
    "a = model.coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 截距\n",
    "b = model.intercept_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 获得线性函数\n",
    "def f(x):\n",
    "    return a*x + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x1a19465320>]"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y)\n",
    "plt.plot(x, f(x), color='red')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.4 模型预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_pred = model.predict(x.reshape(-1, 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 训练值-预测值，可视化图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x1a19598e10>]"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x.reshape(-1, 1), y_train_pred)\n",
    "plt.scatter(x.reshape(-1, 1), y_, color='yellow')\n",
    "plt.plot(x, f(x), color='red')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. Complete the unfinished KNN Model using pure python to solve the previous Line-Regression problem. (8 points)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<评阅点>:\n",
    "> + 是否完成了KNN模型 (4')\n",
    "+ 是否能够预测新的数据 (4')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 算法描述\n",
    "1）计算测试数据与各个训练数据之间的距离；\n",
    "\n",
    "2）按照距离的递增关系进行排序；\n",
    "\n",
    "3）选取距离最小的K个点；\n",
    "\n",
    "4）确定前K个点所在类别的出现频率；\n",
    "\n",
    "5）返回前K个点中出现频率最高的类别作为测试数据的预测分类。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "def model(x, y):\n",
    "    return [(xi, yi) for xi, yi in zip(x, y)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(0.12961767590130946, 0.05207923765528222),\n",
       " (0.45784653743303527, 0.6360503399565344),\n",
       " (0.5725130652067008, 0.01674640189178722),\n",
       " (0.9745878421685487, 0.753986092936857),\n",
       " (0.06333257178645213, 0.6134848321376926),\n",
       " (0.18605239027603737, 0.6144074012994564),\n",
       " (0.7957125040589772, 0.7681125040918174),\n",
       " (0.00016278643073452947, 0.278860838524145),\n",
       " (0.15174185231933268, 0.1859256707078305),\n",
       " (0.6514085776208884, 0.6317258864492381),\n",
       " (0.6171328489699667, 0.3430572558497964),\n",
       " (0.789150352748268, 0.251046052751009),\n",
       " (0.40237352303512697, 0.2417932895443352),\n",
       " (0.22173491285893, 0.3647025277300099),\n",
       " (0.6515977284334963, 0.5247349158456543),\n",
       " (0.330260143075813, 0.29008990648624766),\n",
       " (0.4855650428445929, 0.43979168217026776),\n",
       " (0.5644248094475289, 0.40237409513901845),\n",
       " (0.1454539414377768, 0.19637030877208694),\n",
       " (0.5420135449783883, 0.4119082375398476)]"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model(x,y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算一维数组之间的余弦距离\n",
    "from scipy.spatial.distance import cosine"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "def distance(x1, x2):\n",
    "    return cosine(x1, x2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict(x_, k=6):\n",
    "    most_simiars = sorted(model(x, y), key=lambda xi: distance(xi[0], x_))[:k]\n",
    "    print(most_simiars)\n",
    "    y_hats = [_y for x, _y in most_simiars]\n",
    "    return np.mean(y_hats)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 预测新数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(0.1454539414377768, 0.19637030877208694), (0.45784653743303527, 0.6360503399565344), (0.5725130652067008, 0.01674640189178722), (0.9745878421685487, 0.753986092936857), (0.06333257178645213, 0.6134848321376926), (0.18605239027603737, 0.6144074012994564)]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.4718408961657357"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict(0.8)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. Re-code the Decision Tree, which could sort the features by salience. (12 points)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<评阅点>\n",
    "> + 是否实现了信息熵 (1' )\n",
    "+ 是否实现了最优先特征点的选择(5')\n",
    "+ 是否实现了持续的特征选则(6')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.1 信息熵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import Counter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: icecream in /Users/stone/anaconda3/lib/python3.7/site-packages (2.0.0)\n",
      "Requirement already satisfied: executing>=0.3.1 in /Users/stone/anaconda3/lib/python3.7/site-packages (from icecream) (0.4.1)\n",
      "Requirement already satisfied: asttokens>=2.0.1 in /Users/stone/anaconda3/lib/python3.7/site-packages (from icecream) (2.0.3)\n",
      "Requirement already satisfied: pygments>=2.2.0 in /Users/stone/anaconda3/lib/python3.7/site-packages (from icecream) (2.3.1)\n",
      "Requirement already satisfied: colorama>=0.3.9 in /Users/stone/anaconda3/lib/python3.7/site-packages (from icecream) (0.4.1)\n",
      "Requirement already satisfied: six in /Users/stone/anaconda3/lib/python3.7/site-packages (from asttokens>=2.0.1->icecream) (1.12.0)\n"
     ]
    }
   ],
   "source": [
    "!pip install icecream"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "from icecream import ic"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$ Entropy = -\\sum_i^n Pr(x_i)log(Pr(x_i)) $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "def entropy(elements_list):\n",
    "    length = len(elements_list)\n",
    "    counter = Counter(elements_list)\n",
    "    probs = [counter[c] / length for c in set(elements_list)]\n",
    "#     print(probs)\n",
    "    ic(probs)\n",
    "    # 不写底数时默认以e为底\n",
    "    return -sum(p * np.log(p) for p in probs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "elements_list = [[1, 3, 4, 1], [1, 3, -4, 1], [1, 2, 2, 1], [1, 1, 1, 1]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ic| probs: [0.5, 0.25, 0.25]\n",
      "ic| probs: [0.5, 0.25, 0.25]\n",
      "ic| probs: [0.5, 0.5]\n",
      "ic| probs: [1.0]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 3, 4, 1] ==> 1.0397207708399179\n",
      "[1, 3, -4, 1] ==> 1.0397207708399179\n",
      "[1, 2, 2, 1] ==> 0.6931471805599453\n",
      "[1, 1, 1, 1] ==> -0.0\n"
     ]
    }
   ],
   "source": [
    "for e in elements_list:\n",
    "    print(str(e),'==>', entropy(e))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.2 决策树"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "mock_data = {\n",
    "    'gender':['F', 'F', 'F', 'F', 'M', 'M', 'M'],\n",
    "    'income': ['+10', '-10', '+10', '+10', '+10', '+10', '-10'],\n",
    "    'family_number': [1, 1, 2, 1, 1, 1, 2],\n",
    "    'bought': [1, 1, 1, 0, 0, 0, 1],\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset = pd.DataFrame.from_dict(mock_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>gender</th>\n",
       "      <th>income</th>\n",
       "      <th>family_number</th>\n",
       "      <th>bought</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>F</td>\n",
       "      <td>-10</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>M</td>\n",
       "      <td>-10</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  gender income  family_number  bought\n",
       "0      F    +10              1       1\n",
       "1      F    -10              1       1\n",
       "2      F    +10              2       1\n",
       "3      F    +10              1       0\n",
       "4      M    +10              1       0\n",
       "5      M    +10              1       0\n",
       "6      M    -10              2       1"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ic| probs: [0.25, 0.75]\n",
      "ic| probs: [0.6666666666666666, 0.3333333333333333]\n",
      "ic| probs: [0.6, 0.4]\n",
      "ic| probs: [1.0]\n",
      "ic| probs: [0.6, 0.4]\n",
      "ic| probs: [1.0]\n",
      "ic| probs: [1.0]\n",
      "ic| probs: [1.0]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "split_by_gender: 1.198849312913621\n",
      "split_by_income: 0.6730116670092565\n",
      "split_by_family_number 0.6730116670092565\n",
      "split_by_pet: -0.0\n"
     ]
    }
   ],
   "source": [
    "# split_by_gender: \n",
    "print(\"split_by_gender:\",entropy([1, 1, 1, 0]) + entropy([0, 0, 1]))\n",
    "\n",
    "# split_by_income:\n",
    "print(\"split_by_income:\",entropy([1, 1, 0, 0, 0]) + entropy([1, 1]))\n",
    "\n",
    "# split_by_family_number\n",
    "print(\"split_by_family_number\",entropy([1, 1, 0, 0, 0]) + entropy([1, 1]))\n",
    "\n",
    "# split_by_pet\n",
    "print(\"split_by_pet:\",entropy([1, 1, 1, 1]) + entropy([0, 0, 0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0     True\n",
      "1     True\n",
      "2    False\n",
      "3     True\n",
      "4     True\n",
      "5     True\n",
      "6    False\n",
      "Name: family_number, dtype: bool\n"
     ]
    }
   ],
   "source": [
    "print(dataset['family_number'] == 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    1\n",
       "1    1\n",
       "2    1\n",
       "3    0\n",
       "4    0\n",
       "5    0\n",
       "6    1\n",
       "Name: bought, dtype: int64"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset['bought']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "sub_split_1 = dataset[dataset['family_number'] == 1]['bought'].tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 1, 0, 0, 0]"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sub_split_1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [],
   "source": [
    "splited_data = dataset[dataset['family_number'] == 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>gender</th>\n",
       "      <th>income</th>\n",
       "      <th>family_number</th>\n",
       "      <th>bought</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>F</td>\n",
       "      <td>-10</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  gender income  family_number  bought\n",
       "0      F    +10              1       1\n",
       "1      F    -10              1       1\n",
       "3      F    +10              1       0\n",
       "4      M    +10              1       0\n",
       "5      M    +10              1       0"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "splited_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>gender</th>\n",
       "      <th>income</th>\n",
       "      <th>family_number</th>\n",
       "      <th>bought</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  gender income  family_number  bought\n",
       "0      F    +10              1       1\n",
       "3      F    +10              1       0\n",
       "4      M    +10              1       0\n",
       "5      M    +10              1       0"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "splited_data[splited_data['income'] == '+10']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "def find_optimal_spilter(train_data: pd.DataFrame, target: str) -> str:\n",
    "    # set(train_data.columns.tolist()): {'family_number', 'income', 'gender', 'pet', 'bought'}\n",
    "    x_fields = set(train_data.columns.tolist()) - {target}\n",
    "#     print(x_fields)\n",
    "    spliter = None\n",
    "    min_entropy = float('inf')\n",
    "    for f in x_fields:\n",
    "        \"\"\"\n",
    "            values:\n",
    "                {'M', 'F'}\n",
    "                {1, 2}\n",
    "                {'-10', '+10'}\n",
    "                {0, 1}\n",
    "        \"\"\"\n",
    "        values = set(train_data[f])\n",
    "        print(values)\n",
    "        for v in values:\n",
    "            sub_spliter_1 = train_data[train_data[f] == v][target].tolist()\n",
    "            ic(sub_spliter_1)\n",
    "            entropy_1 = entropy(sub_spliter_1)\n",
    "            \n",
    "            sub_spliter_2 = train_data[train_data[f] != v][target].tolist()\n",
    "            ic(sub_spliter_2)\n",
    "            entropy_2 = entropy(sub_spliter_2)\n",
    "            \n",
    "            entropy_v = entropy_1 + entropy_2\n",
    "            ic(entropy_v)\n",
    "            \n",
    "            if entropy_v <= min_entropy:\n",
    "                min_entropy = entropy_v\n",
    "                spliter = (f, v)\n",
    "    print('spliter is: {}'.format(spliter))\n",
    "    print('the min entropy is: {}'.format(min_entropy))\n",
    "    \n",
    "    return spliter, min_entropy     \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ic| sub_spliter_1: [1, 1, 1, 0]\n",
      "ic| probs: [0.25, 0.75]\n",
      "ic| sub_spliter_2: [0, 0, 1]\n",
      "ic| probs: [0.6666666666666666, 0.3333333333333333]\n",
      "ic| entropy_v: 1.198849312913621\n",
      "ic| sub_spliter_1: [0, 0, 1]\n",
      "ic| probs: [0.6666666666666666, 0.3333333333333333]\n",
      "ic| sub_spliter_2: [1, 1, 1, 0]\n",
      "ic| probs: [0.25, 0.75]\n",
      "ic| entropy_v: 1.198849312913621\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'F', 'M'}\n",
      "{'+10', '-10'}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ic| sub_spliter_1: [1, 1, 0, 0, 0]\n",
      "ic| probs: [0.6, 0.4]\n",
      "ic| sub_spliter_2: [1, 1]\n",
      "ic| probs: [1.0]\n",
      "ic| entropy_v: 0.6730116670092565\n",
      "ic| sub_spliter_1: [1, 1]\n",
      "ic| probs: [1.0]\n",
      "ic| sub_spliter_2: [1, 1, 0, 0, 0]\n",
      "ic| probs: [0.6, 0.4]\n",
      "ic| entropy_v: 0.6730116670092565\n",
      "ic| sub_spliter_1: [1, 1, 0, 0, 0]\n",
      "ic| probs: [0.6, 0.4]\n",
      "ic| sub_spliter_2: [1, 1]\n",
      "ic| probs: [1.0]\n",
      "ic| entropy_v: 0.6730116670092565\n",
      "ic| sub_spliter_1: [1, 1]\n",
      "ic| probs: [1.0]\n",
      "ic| sub_spliter_2: [1, 1, 0, 0, 0]\n",
      "ic| probs: [0.6, 0.4]\n",
      "ic| entropy_v: 0.6730116670092565\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2}\n",
      "spliter is: ('family_number', 2)\n",
      "the min entropy is: 0.6730116670092565\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "('family_number', 2)"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "find_optimal_spilter(train_data=dataset, target='bought')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### - 先按照(family_number, 2), 进行划分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ic| sub_spliter_1: [1, 1, 0]\n",
      "ic| probs: [0.3333333333333333, 0.6666666666666666]\n",
      "ic| sub_spliter_2: [0, 0]\n",
      "ic| probs: [1.0]\n",
      "ic| entropy_v: 0.6365141682948128\n",
      "ic| sub_spliter_1: [0, 0]\n",
      "ic| probs: [1.0]\n",
      "ic| sub_spliter_2: [1, 1, 0]\n",
      "ic| probs: [0.3333333333333333, 0.6666666666666666]\n",
      "ic| entropy_v: 0.6365141682948128\n",
      "ic| sub_spliter_1: [1"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'F', 'M'}\n",
      "{'+10', '-10'}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      ", 0, 0, 0]\n",
      "ic| probs: [0.75, 0.25]\n",
      "ic| sub_spliter_2: [1]\n",
      "ic| probs: [1.0]\n",
      "ic| entropy_v: 0.5623351446188083\n",
      "ic| sub_spliter_1: [1]\n",
      "ic| probs: [1.0]\n",
      "ic| sub_spliter_2: [1, 0, 0, 0]\n",
      "ic| probs: [0.75, 0.25]\n",
      "ic| entropy_v: 0.5623351446188083\n",
      "ic| sub_spliter_1: [1, 1, 0, 0, 0]\n",
      "ic| probs: [0.6, 0.4]\n",
      "ic| sub_spliter_2: []\n",
      "ic| probs: []\n",
      "ic| entropy_v: 0.6730116670092565\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1}\n",
      "spliter is: ('income', '-10')\n",
      "the min entropy is: 0.5623351446188083\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "('income', '-10')"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "find_optimal_spilter(dataset[dataset['family_number'] == 1], 'bought')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [],
   "source": [
    "fm_n_1 = dataset[dataset['family_number'] == 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>gender</th>\n",
       "      <th>income</th>\n",
       "      <th>family_number</th>\n",
       "      <th>bought</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>F</td>\n",
       "      <td>-10</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  gender income  family_number  bought\n",
       "0      F    +10              1       1\n",
       "1      F    -10              1       1\n",
       "3      F    +10              1       0\n",
       "4      M    +10              1       0\n",
       "5      M    +10              1       0"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fm_n_1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>gender</th>\n",
       "      <th>income</th>\n",
       "      <th>family_number</th>\n",
       "      <th>bought</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  gender income  family_number  bought\n",
       "0      F    +10              1       1\n",
       "3      F    +10              1       0\n",
       "4      M    +10              1       0\n",
       "5      M    +10              1       0"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fm_n_1[fm_n_1['income'] == '+10']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>gender</th>\n",
       "      <th>income</th>\n",
       "      <th>family_number</th>\n",
       "      <th>bought</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>F</td>\n",
       "      <td>-10</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  gender income  family_number  bought\n",
       "1      F    -10              1       1"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fm_n_1[fm_n_1['income'] != '+10']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ic| sub_spliter_1: [1, 0]\n",
      "ic| probs: [0.5, 0.5]\n",
      "ic| sub_spliter_2: [0, 0]\n",
      "ic| probs: [1.0]\n",
      "ic| entropy_v: 0.6931471805599453\n",
      "ic| sub_spliter_1: [0, 0]\n",
      "ic| probs: [1.0]\n",
      "ic| sub_spliter_2: [1, 0]\n",
      "ic| probs: [0.5, 0.5]\n",
      "ic| entropy_v: 0.6931471805599453\n",
      "ic| sub_spliter_1: [1,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'F', 'M'}\n",
      "{'+10'}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " 0, 0, 0]\n",
      "ic| probs: [0.75, 0.25]\n",
      "ic| sub_spliter_2: []\n",
      "ic| probs: []\n",
      "ic| entropy_v: 0.5623351446188083\n",
      "ic| sub_spliter_1: [1, 0, 0, 0]\n",
      "ic| probs: [0.75, 0.25]\n",
      "ic| sub_spliter_2: []\n",
      "ic| probs: []\n",
      "ic| entropy_v: 0.5623351446188083\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1}\n",
      "spliter is: ('family_number', 1)\n",
      "the min entropy is: 0.5623351446188083\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "('family_number', 1)"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "find_optimal_spilter(fm_n_1[fm_n_1['income'] == '+10'], 'bought')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 反复调用find_optimal_spilter， 获取整个完整决策树，存放进dict中\n",
    "def get_tree(train_data: pd.DataFrame, target: str):\n",
    "    tree = {}\n",
    "    while True:\n",
    "        # 寻找最优划分\n",
    "        (k, v), min_entropy = find_optimal_spilter(train_data=train_data, target=target)\n",
    "        tree[k] = v\n",
    "        if min_entropy == 0:\n",
    "            break\n",
    "        # 获取下一数据表\n",
    "        train_data = train_data[train_data[k] != v]\n",
    "        print(train_data)\n",
    "        train_data = train_data.drop([k],axis=1)\n",
    "        # 直到为0\n",
    "        if len(train_data.columns) == 1:\n",
    "            break\n",
    "        if train_data.shape[0] == 0:\n",
    "            break     \n",
    "    i = 0\n",
    "    print(\"划分如下：\")\n",
    "    for k,v in tree.items():\n",
    "        i += 1\n",
    "        print(\"第(%d)次，为(%s)\" %(i,(k,v)))    \n",
    "    return tree        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>gender</th>\n",
       "      <th>income</th>\n",
       "      <th>family_number</th>\n",
       "      <th>bought</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>F</td>\n",
       "      <td>-10</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>F</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>M</td>\n",
       "      <td>+10</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>M</td>\n",
       "      <td>-10</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  gender income  family_number  bought\n",
       "0      F    +10              1       1\n",
       "1      F    -10              1       1\n",
       "2      F    +10              2       1\n",
       "3      F    +10              1       0\n",
       "4      M    +10              1       0\n",
       "5      M    +10              1       0\n",
       "6      M    -10              2       1"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ic| sub_spliter_1: [1, 1, 1, 0]\n",
      "ic| probs: [0.25, 0.75]\n",
      "ic| sub_spliter_2: [0, 0, 1]\n",
      "ic| probs: [0.6666666666666666, 0.3333333333333333]\n",
      "ic| entropy_v: 1.198849312913621\n",
      "ic| sub_spliter_1: [0, 0, 1]\n",
      "ic| probs: [0.6666666666666666, 0.3333333333333333]\n",
      "ic| sub_spliter_2: "
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'F', 'M'}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[1, 1, 1, 0]\n",
      "ic| probs: [0.25, 0.75]\n",
      "ic| entropy_v: 1.198849312913621\n",
      "ic| sub_spliter_1: [1, 1, 0, 0, 0]\n",
      "ic| probs: [0.6, 0.4]\n",
      "ic| sub_spliter_2: [1, 1]\n",
      "ic| probs: [1.0]\n",
      "ic| entropy_v: 0.6730116670092565\n",
      "ic| sub_spliter_1: [1, 1]\n",
      "ic| probs: [1.0]\n",
      "ic| sub_spliter_2: [1, 1, 0, 0, 0]\n",
      "ic| probs: [0.6, 0.4]\n",
      "ic| entropy_v: 0.6730116670092565\n",
      "ic| sub_spliter_1: [1, 1, 0"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'+10', '-10'}\n",
      "{1, 2}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      ", 0, 0]\n",
      "ic| probs: [0.6, 0.4]\n",
      "ic| sub_spliter_2: [1, 1]\n",
      "ic| probs: [1.0]\n",
      "ic| entropy_v: 0.6730116670092565\n",
      "ic| sub_spliter_1: [1, 1]\n",
      "ic| probs: [1.0]\n",
      "ic| sub_spliter_2: [1, 1, 0, 0, 0]\n",
      "ic| probs: [0.6, 0.4]\n",
      "ic| entropy_v: 0.6730116670092565\n",
      "ic| sub_spliter_1: [1, 1, 0]\n",
      "ic| probs: [0.3333333333333333, 0.6666666666666666]\n",
      "ic| sub_spliter_2: [0, 0]\n",
      "ic| probs: [1.0]\n",
      "ic| entropy_v: 0.6365141682948128\n",
      "ic| sub_spliter_1: [0, 0]\n",
      "ic| probs: [1.0]\n",
      "ic| sub_spliter_2: [1, 1, 0]\n",
      "ic| probs: [0.3333333333333333, 0.6666666666666666]\n",
      "ic| entropy_v: 0.6365141682948128\n",
      "ic| sub_spliter_1"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "spliter is: ('family_number', 2)\n",
      "the min entropy is: 0.6730116670092565\n",
      "  gender income  family_number  bought\n",
      "0      F    +10              1       1\n",
      "1      F    -10              1       1\n",
      "3      F    +10              1       0\n",
      "4      M    +10              1       0\n",
      "5      M    +10              1       0\n",
      "{'F', 'M'}\n",
      "{'+10', '-10'}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      ": [1, 0, 0, 0]\n",
      "ic| probs: [0.75, 0.25]\n",
      "ic| sub_spliter_2: [1]\n",
      "ic| probs: [1.0]\n",
      "ic| entropy_v: 0.5623351446188083\n",
      "ic| sub_spliter_1: [1]\n",
      "ic| probs: [1.0]\n",
      "ic| sub_spliter_2: [1, 0, 0, 0]\n",
      "ic| probs: [0.75, 0.25]\n",
      "ic| entropy_v: 0.5623351446188083\n",
      "ic| sub_spliter_1: [1, 0]\n",
      "ic| probs: [0.5, 0.5]\n",
      "ic| sub_spliter_2: [0, 0]\n",
      "ic| probs: [1.0]\n",
      "ic| entropy_v: 0.6931471805599453\n",
      "ic| sub_spliter_1: [0, 0]\n",
      "ic| probs: [1.0]\n",
      "ic| sub_spliter_2: [1, 0]\n",
      "ic| probs: [0.5, 0.5]\n",
      "ic| entropy_v: 0.6931471805599453\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "spliter is: ('income', '-10')\n",
      "the min entropy is: 0.5623351446188083\n",
      "  gender income  bought\n",
      "0      F    +10       1\n",
      "3      F    +10       0\n",
      "4      M    +10       0\n",
      "5      M    +10       0\n",
      "{'F', 'M'}\n",
      "spliter is: ('gender', 'M')\n",
      "the min entropy is: 0.6931471805599453\n",
      "  gender  bought\n",
      "0      F       1\n",
      "3      F       0\n",
      "划分如下：\n",
      "第(1)次，为(('family_number', 2))\n",
      "第(2)次，为(('income', '-10'))\n",
      "第(3)次，为(('gender', 'M'))\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'family_number': 2, 'income': '-10', 'gender': 'M'}"
      ]
     },
     "execution_count": 101,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_tree(train_data=dataset, target='bought')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. Finish the K-Means using 2-D matplotlib (8 points)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<评阅点>\n",
    "> + 是否完成了KMeans模型，基于scikit-learning (3')\n",
    "+ 是否完成了可视化任务（5'）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 159,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.cluster import KMeans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 169,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_test_random = random.randint(0, 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 170,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 170,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_test_random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 176,
   "metadata": {},
   "outputs": [],
   "source": [
    "X1 = [random.randint(0, 100) for _ in range(100)]\n",
    "X2 = [random.randint(0, 100) for _ in range(100)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 177,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[100,\n",
       " 21,\n",
       " 72,\n",
       " 20,\n",
       " 96,\n",
       " 94,\n",
       " 20,\n",
       " 15,\n",
       " 24,\n",
       " 48,\n",
       " 31,\n",
       " 23,\n",
       " 36,\n",
       " 17,\n",
       " 66,\n",
       " 26,\n",
       " 47,\n",
       " 41,\n",
       " 46,\n",
       " 89,\n",
       " 98,\n",
       " 7,\n",
       " 94,\n",
       " 64,\n",
       " 13,\n",
       " 92,\n",
       " 71,\n",
       " 44,\n",
       " 6,\n",
       " 28,\n",
       " 57,\n",
       " 31,\n",
       " 92,\n",
       " 90,\n",
       " 46,\n",
       " 0,\n",
       " 17,\n",
       " 68,\n",
       " 41,\n",
       " 2,\n",
       " 48,\n",
       " 80,\n",
       " 35,\n",
       " 53,\n",
       " 53,\n",
       " 83,\n",
       " 0,\n",
       " 54,\n",
       " 16,\n",
       " 21,\n",
       " 40,\n",
       " 7,\n",
       " 48,\n",
       " 18,\n",
       " 81,\n",
       " 27,\n",
       " 4,\n",
       " 30,\n",
       " 20,\n",
       " 59,\n",
       " 97,\n",
       " 21,\n",
       " 9,\n",
       " 76,\n",
       " 41,\n",
       " 37,\n",
       " 71,\n",
       " 45,\n",
       " 34,\n",
       " 22,\n",
       " 97,\n",
       " 0,\n",
       " 83,\n",
       " 24,\n",
       " 4,\n",
       " 54,\n",
       " 59,\n",
       " 44,\n",
       " 57,\n",
       " 94,\n",
       " 25,\n",
       " 52,\n",
       " 71,\n",
       " 43,\n",
       " 54,\n",
       " 50,\n",
       " 98,\n",
       " 27,\n",
       " 50,\n",
       " 86,\n",
       " 24,\n",
       " 49,\n",
       " 0,\n",
       " 38,\n",
       " 7,\n",
       " 11,\n",
       " 40,\n",
       " 40,\n",
       " 0,\n",
       " 10]"
      ]
     },
     "execution_count": 177,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 178,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x1a21eae208>"
      ]
     },
     "execution_count": 178,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 画出散点图\n",
    "plt.scatter(x1, x2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 179,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data = [[x1, x2] for x1, x2 in zip(X1, X2)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 180,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[100, 39],\n",
       " [21, 77],\n",
       " [72, 38],\n",
       " [20, 42],\n",
       " [96, 75],\n",
       " [94, 31],\n",
       " [20, 32],\n",
       " [15, 58],\n",
       " [24, 55],\n",
       " [48, 40],\n",
       " [31, 60],\n",
       " [23, 93],\n",
       " [36, 23],\n",
       " [17, 89],\n",
       " [66, 98],\n",
       " [26, 22],\n",
       " [47, 47],\n",
       " [41, 73],\n",
       " [46, 45],\n",
       " [89, 18],\n",
       " [98, 49],\n",
       " [7, 1],\n",
       " [94, 51],\n",
       " [64, 30],\n",
       " [13, 50],\n",
       " [92, 58],\n",
       " [71, 15],\n",
       " [44, 19],\n",
       " [6, 26],\n",
       " [28, 39],\n",
       " [57, 29],\n",
       " [31, 99],\n",
       " [92, 2],\n",
       " [90, 33],\n",
       " [46, 50],\n",
       " [0, 16],\n",
       " [17, 35],\n",
       " [68, 68],\n",
       " [41, 69],\n",
       " [2, 84],\n",
       " [48, 8],\n",
       " [80, 20],\n",
       " [35, 59],\n",
       " [53, 28],\n",
       " [53, 35],\n",
       " [83, 68],\n",
       " [0, 61],\n",
       " [54, 30],\n",
       " [16, 74],\n",
       " [21, 62],\n",
       " [40, 43],\n",
       " [7, 9],\n",
       " [48, 87],\n",
       " [18, 25],\n",
       " [81, 2],\n",
       " [27, 25],\n",
       " [4, 3],\n",
       " [30, 81],\n",
       " [20, 96],\n",
       " [59, 9],\n",
       " [97, 22],\n",
       " [21, 94],\n",
       " [9, 46],\n",
       " [76, 64],\n",
       " [41, 11],\n",
       " [37, 21],\n",
       " [71, 90],\n",
       " [45, 26],\n",
       " [34, 68],\n",
       " [22, 30],\n",
       " [97, 71],\n",
       " [0, 88],\n",
       " [83, 100],\n",
       " [24, 15],\n",
       " [4, 64],\n",
       " [54, 45],\n",
       " [59, 47],\n",
       " [44, 97],\n",
       " [57, 12],\n",
       " [94, 40],\n",
       " [25, 100],\n",
       " [52, 22],\n",
       " [71, 46],\n",
       " [43, 6],\n",
       " [54, 19],\n",
       " [50, 35],\n",
       " [98, 34],\n",
       " [27, 40],\n",
       " [50, 92],\n",
       " [86, 85],\n",
       " [24, 55],\n",
       " [49, 44],\n",
       " [0, 69],\n",
       " [38, 91],\n",
       " [7, 16],\n",
       " [11, 41],\n",
       " [40, 24],\n",
       " [40, 86],\n",
       " [0, 30],\n",
       " [10, 88]]"
      ]
     },
     "execution_count": 180,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 183,
   "metadata": {},
   "outputs": [],
   "source": [
    "cluster = KMeans(n_clusters=6, max_iter=500)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 184,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=500,\n",
       "    n_clusters=6, n_init=10, n_jobs=None, precompute_distances='auto',\n",
       "    random_state=None, tol=0.0001, verbose=0)"
      ]
     },
     "execution_count": 184,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cluster.fit(train_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 185,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[49.07692308, 28.76923077],\n",
       "       [27.6       , 86.3       ],\n",
       "       [81.8       , 77.7       ],\n",
       "       [17.46666667, 53.4       ],\n",
       "       [88.06666667, 29.33333333],\n",
       "       [13.21428571, 20.35714286]])"
      ]
     },
     "execution_count": 185,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cluster.cluster_centers_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 186,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4, 1, 4, 3, 2, 4, 5, 3, 3, 0, 3, 1, 0, 1, 2, 5, 0, 1, 0, 4, 4, 5,\n",
       "       4, 0, 3, 2, 4, 0, 5, 3, 0, 1, 4, 4, 0, 5, 5, 2, 1, 1, 0, 4, 3, 0,\n",
       "       0, 2, 3, 0, 1, 3, 0, 5, 1, 5, 4, 5, 5, 1, 1, 0, 4, 1, 3, 2, 0, 0,\n",
       "       2, 0, 1, 5, 2, 1, 2, 5, 3, 0, 0, 1, 0, 4, 1, 0, 4, 0, 0, 0, 4, 3,\n",
       "       1, 2, 3, 0, 3, 1, 5, 3, 0, 1, 5, 1], dtype=int32)"
      ]
     },
     "execution_count": 186,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cluster.labels_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 187,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import defaultdict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 188,
   "metadata": {},
   "outputs": [],
   "source": [
    "centers = defaultdict(list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 192,
   "metadata": {},
   "outputs": [],
   "source": [
    "for label, location in zip(cluster.labels_, train_data):\n",
    "    centers[label].append(location)\n",
    "# print(centers)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 193,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defaultdict(list,\n",
       "            {4: [[100, 39],\n",
       "              [72, 38],\n",
       "              [94, 31],\n",
       "              [89, 18],\n",
       "              [98, 49],\n",
       "              [94, 51],\n",
       "              [71, 15],\n",
       "              [92, 2],\n",
       "              [90, 33],\n",
       "              [80, 20],\n",
       "              [81, 2],\n",
       "              [97, 22],\n",
       "              [94, 40],\n",
       "              [71, 46],\n",
       "              [98, 34],\n",
       "              [100, 39],\n",
       "              [72, 38],\n",
       "              [94, 31],\n",
       "              [89, 18],\n",
       "              [98, 49],\n",
       "              [94, 51],\n",
       "              [71, 15],\n",
       "              [92, 2],\n",
       "              [90, 33],\n",
       "              [80, 20],\n",
       "              [81, 2],\n",
       "              [97, 22],\n",
       "              [94, 40],\n",
       "              [71, 46],\n",
       "              [98, 34],\n",
       "              [100, 39],\n",
       "              [72, 38],\n",
       "              [94, 31],\n",
       "              [89, 18],\n",
       "              [98, 49],\n",
       "              [94, 51],\n",
       "              [71, 15],\n",
       "              [92, 2],\n",
       "              [90, 33],\n",
       "              [80, 20],\n",
       "              [81, 2],\n",
       "              [97, 22],\n",
       "              [94, 40],\n",
       "              [71, 46],\n",
       "              [98, 34]],\n",
       "             1: [[21, 77],\n",
       "              [23, 93],\n",
       "              [17, 89],\n",
       "              [41, 73],\n",
       "              [31, 99],\n",
       "              [41, 69],\n",
       "              [2, 84],\n",
       "              [16, 74],\n",
       "              [48, 87],\n",
       "              [30, 81],\n",
       "              [20, 96],\n",
       "              [21, 94],\n",
       "              [34, 68],\n",
       "              [0, 88],\n",
       "              [44, 97],\n",
       "              [25, 100],\n",
       "              [50, 92],\n",
       "              [38, 91],\n",
       "              [40, 86],\n",
       "              [10, 88],\n",
       "              [21, 77],\n",
       "              [23, 93],\n",
       "              [17, 89],\n",
       "              [41, 73],\n",
       "              [31, 99],\n",
       "              [41, 69],\n",
       "              [2, 84],\n",
       "              [16, 74],\n",
       "              [48, 87],\n",
       "              [30, 81],\n",
       "              [20, 96],\n",
       "              [21, 94],\n",
       "              [34, 68],\n",
       "              [0, 88],\n",
       "              [44, 97],\n",
       "              [25, 100],\n",
       "              [50, 92],\n",
       "              [38, 91],\n",
       "              [40, 86],\n",
       "              [10, 88],\n",
       "              [21, 77],\n",
       "              [23, 93],\n",
       "              [17, 89],\n",
       "              [41, 73],\n",
       "              [31, 99],\n",
       "              [41, 69],\n",
       "              [2, 84],\n",
       "              [16, 74],\n",
       "              [48, 87],\n",
       "              [30, 81],\n",
       "              [20, 96],\n",
       "              [21, 94],\n",
       "              [34, 68],\n",
       "              [0, 88],\n",
       "              [44, 97],\n",
       "              [25, 100],\n",
       "              [50, 92],\n",
       "              [38, 91],\n",
       "              [40, 86],\n",
       "              [10, 88]],\n",
       "             3: [[20, 42],\n",
       "              [15, 58],\n",
       "              [24, 55],\n",
       "              [31, 60],\n",
       "              [13, 50],\n",
       "              [28, 39],\n",
       "              [35, 59],\n",
       "              [0, 61],\n",
       "              [21, 62],\n",
       "              [9, 46],\n",
       "              [4, 64],\n",
       "              [27, 40],\n",
       "              [24, 55],\n",
       "              [0, 69],\n",
       "              [11, 41],\n",
       "              [20, 42],\n",
       "              [15, 58],\n",
       "              [24, 55],\n",
       "              [31, 60],\n",
       "              [13, 50],\n",
       "              [28, 39],\n",
       "              [35, 59],\n",
       "              [0, 61],\n",
       "              [21, 62],\n",
       "              [9, 46],\n",
       "              [4, 64],\n",
       "              [27, 40],\n",
       "              [24, 55],\n",
       "              [0, 69],\n",
       "              [11, 41],\n",
       "              [20, 42],\n",
       "              [15, 58],\n",
       "              [24, 55],\n",
       "              [31, 60],\n",
       "              [13, 50],\n",
       "              [28, 39],\n",
       "              [35, 59],\n",
       "              [0, 61],\n",
       "              [21, 62],\n",
       "              [9, 46],\n",
       "              [4, 64],\n",
       "              [27, 40],\n",
       "              [24, 55],\n",
       "              [0, 69],\n",
       "              [11, 41]],\n",
       "             2: [[96, 75],\n",
       "              [66, 98],\n",
       "              [92, 58],\n",
       "              [68, 68],\n",
       "              [83, 68],\n",
       "              [76, 64],\n",
       "              [71, 90],\n",
       "              [97, 71],\n",
       "              [83, 100],\n",
       "              [86, 85],\n",
       "              [96, 75],\n",
       "              [66, 98],\n",
       "              [92, 58],\n",
       "              [68, 68],\n",
       "              [83, 68],\n",
       "              [76, 64],\n",
       "              [71, 90],\n",
       "              [97, 71],\n",
       "              [83, 100],\n",
       "              [86, 85],\n",
       "              [96, 75],\n",
       "              [66, 98],\n",
       "              [92, 58],\n",
       "              [68, 68],\n",
       "              [83, 68],\n",
       "              [76, 64],\n",
       "              [71, 90],\n",
       "              [97, 71],\n",
       "              [83, 100],\n",
       "              [86, 85]],\n",
       "             5: [[20, 32],\n",
       "              [26, 22],\n",
       "              [7, 1],\n",
       "              [6, 26],\n",
       "              [0, 16],\n",
       "              [17, 35],\n",
       "              [7, 9],\n",
       "              [18, 25],\n",
       "              [27, 25],\n",
       "              [4, 3],\n",
       "              [22, 30],\n",
       "              [24, 15],\n",
       "              [7, 16],\n",
       "              [0, 30],\n",
       "              [20, 32],\n",
       "              [26, 22],\n",
       "              [7, 1],\n",
       "              [6, 26],\n",
       "              [0, 16],\n",
       "              [17, 35],\n",
       "              [7, 9],\n",
       "              [18, 25],\n",
       "              [27, 25],\n",
       "              [4, 3],\n",
       "              [22, 30],\n",
       "              [24, 15],\n",
       "              [7, 16],\n",
       "              [0, 30],\n",
       "              [20, 32],\n",
       "              [26, 22],\n",
       "              [7, 1],\n",
       "              [6, 26],\n",
       "              [0, 16],\n",
       "              [17, 35],\n",
       "              [7, 9],\n",
       "              [18, 25],\n",
       "              [27, 25],\n",
       "              [4, 3],\n",
       "              [22, 30],\n",
       "              [24, 15],\n",
       "              [7, 16],\n",
       "              [0, 30]],\n",
       "             0: [[48, 40],\n",
       "              [36, 23],\n",
       "              [47, 47],\n",
       "              [46, 45],\n",
       "              [64, 30],\n",
       "              [44, 19],\n",
       "              [57, 29],\n",
       "              [46, 50],\n",
       "              [48, 8],\n",
       "              [53, 28],\n",
       "              [53, 35],\n",
       "              [54, 30],\n",
       "              [40, 43],\n",
       "              [59, 9],\n",
       "              [41, 11],\n",
       "              [37, 21],\n",
       "              [45, 26],\n",
       "              [54, 45],\n",
       "              [59, 47],\n",
       "              [57, 12],\n",
       "              [52, 22],\n",
       "              [43, 6],\n",
       "              [54, 19],\n",
       "              [50, 35],\n",
       "              [49, 44],\n",
       "              [40, 24],\n",
       "              [48, 40],\n",
       "              [36, 23],\n",
       "              [47, 47],\n",
       "              [46, 45],\n",
       "              [64, 30],\n",
       "              [44, 19],\n",
       "              [57, 29],\n",
       "              [46, 50],\n",
       "              [48, 8],\n",
       "              [53, 28],\n",
       "              [53, 35],\n",
       "              [54, 30],\n",
       "              [40, 43],\n",
       "              [59, 9],\n",
       "              [41, 11],\n",
       "              [37, 21],\n",
       "              [45, 26],\n",
       "              [54, 45],\n",
       "              [59, 47],\n",
       "              [57, 12],\n",
       "              [52, 22],\n",
       "              [43, 6],\n",
       "              [54, 19],\n",
       "              [50, 35],\n",
       "              [49, 44],\n",
       "              [40, 24],\n",
       "              [48, 40],\n",
       "              [36, 23],\n",
       "              [47, 47],\n",
       "              [46, 45],\n",
       "              [64, 30],\n",
       "              [44, 19],\n",
       "              [57, 29],\n",
       "              [46, 50],\n",
       "              [48, 8],\n",
       "              [53, 28],\n",
       "              [53, 35],\n",
       "              [54, 30],\n",
       "              [40, 43],\n",
       "              [59, 9],\n",
       "              [41, 11],\n",
       "              [37, 21],\n",
       "              [45, 26],\n",
       "              [54, 45],\n",
       "              [59, 47],\n",
       "              [57, 12],\n",
       "              [52, 22],\n",
       "              [43, 6],\n",
       "              [54, 19],\n",
       "              [50, 35],\n",
       "              [49, 44],\n",
       "              [40, 24]]})"
      ]
     },
     "execution_count": 193,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "centers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 194,
   "metadata": {},
   "outputs": [],
   "source": [
    "color = ['red', 'green', 'grey', 'black', 'yellow', 'orange']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 195,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "for i, c in enumerate(centers):\n",
    "    for location in centers[c]:\n",
    "        plt.scatter(*location, c = color[i]) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 198,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "for center in cluster.cluster_centers_:\n",
    "    plt.scatter(*center, s=200)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 197,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "for i, c in enumerate(centers):\n",
    "    for location in centers[c]:\n",
    "        plt.scatter(*location, c = color[i]) \n",
    "for center in cluster.cluster_centers_:\n",
    "    plt.scatter(*center, s=100)        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 202,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Kmeans距离计算， 就是求解两点之间的距离\n",
    "def distance():\n",
    "    return np.sqrt(x1, x2) ** 2 + (y1 - y2) ** 2"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
